/***************************************************************************
 *   Standard Definitions                                                  *
 *   Copyright (C) 2008 by cmaster.matso (Maciej Kadłubowski)              *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "mgpi_stddefs.h"

MGPI_BOOL g_fState = MGPI_TRUE;                                                 /** global state flag */

/**
 * Creates a float3 vector.
 */
float *vector3(float x, float y, float z) {
    float *vf3 = (float *) calloc(1, sizeof (float *));
    vf3[X] = x;
    vf3[Y] = y;
    vf3[Z] = z;
    return vf3;
}

/**
 * Creates a float3x3 matrix.
 */
float **matrix3(float *predic) {
    int i;
    float **matr3 = (float **) calloc(3, sizeof (float *));

    for (i = 0; i < 3; ++i) matr3[i] = (float *) calloc(3, sizeof (float));
    matr3[X][X] = predic[M11];
    matr3[X][Y] = predic[M12];
    matr3[X][Z] = predic[M13];
    matr3[Y][X] = predic[M14];
    matr3[Y][Y] = predic[M21];
    matr3[Y][Z] = predic[M22];
    matr3[Z][X] = predic[M23];
    matr3[Z][Y] = predic[M24];
    matr3[Z][Z] = predic[M31];

    return matr3;
}

/**
 * Creates a float4 vector.
 */
float *vector4(float x, float y, float z, float w) {
    float *vf4 = (float *) calloc(1, sizeof (float *));
    vf4[X] = x;
    vf4[Y] = y;
    vf4[Z] = z;
    vf4[W] = w;
    return vf4;
}

/**
 * Creates a float4x4 matrix.
 */
float **matrix4(float *predic) {
    int i;
    float **matr4 = (float **) calloc(4, sizeof (float *));

    for (i = 0; i < 4; ++i) matr4[i] = (float *) calloc(4, sizeof (float));

    matr4[X][X] = predic[M11];
    matr4[X][Y] = predic[M12];
    matr4[X][Z] = predic[M13];
    matr4[X][W] = predic[M14];
    matr4[Y][X] = predic[M21];
    matr4[Y][Y] = predic[M22];
    matr4[Y][Z] = predic[M23];
    matr4[Y][W] = predic[M24];
    matr4[Z][X] = predic[M31];
    matr4[Z][Y] = predic[M32];
    matr4[Z][Z] = predic[M33];
    matr4[Z][W] = predic[M34];
    matr4[W][X] = predic[M41];
    matr4[W][Y] = predic[M42];
    matr4[W][Z] = predic[M43];
    matr4[W][W] = predic[M44];

    return matr4;
}

/**
 * Creates an array float3x3 matrix, initialized with zeros.
 */
float *matrix3x3(void) {
    return (float *) calloc(3 * 3, sizeof (float));
}

/**
 * Creates an array float4x4 matrix, initialized with zeros.
 */
float *matrix4x4(void) {
    return (float *) calloc(4 * 4, sizeof (float));
}

/**
 * Creates an array floatnxn matrix, initialized with zeros.
 */
float *matrixnxn(int n) {
    return (float *) calloc(n * n, sizeof (float));
}

/**
 * Creates an array floatnxm matrix, initialized with zeros.
 */
float *matrixnxm(int n, int m) {
    return (float *) calloc(n * m, sizeof (float));
}

/**
 * Devides the given string according to the given number of delim. substrings.
 */
int strstok(char *s, char *delim, int ndelim) {
    char *ptr = s;
    int n = 0, i;
    while (*ptr != '\0') {
        i = 0;
        while (i < ndelim)
            if (*ptr == delim[i++]) {
                ++n;
                *ptr = '\0';
            }
        ptr++;
    }
    return (n / ndelim);
}

/**
 * Returns a number of bytes in the stream given.
 */
long fncbstrm(FILE *stream) {
    fpos_t pos;
    long size;

    fgetpos(stream, &pos);
    fseek(stream, 0, SEEK_END);
    size = ftell(stream);
    fsetpos(stream, &pos);

    return size;
}

/**
 * Loads a file of the given name to a bytes array.
 */
MGPI_BYTE *fload(char *name) {
    FILE *fp;
    MGPI_BYTE *file_buffer = NULL;
    long cnt = 0;

    if (!(fp = fopen(name, "rt"))) {
        MGPI_PostMessagef("%s: couldn't open \"%s\"", __FUN__, name);
        return NULL;
    }

    cnt = fncbstrm(fp);

    fseek(fp, 0, SEEK_SET);
    file_buffer = (MGPI_BYTE *) calloc(cnt, sizeof (MGPI_BYTE));
    fread(file_buffer, sizeof (MGPI_BYTE), cnt, fp);

    fclose(fp);
    return file_buffer;
}

/**
 * Saves given byts array to the file of the given name.
 */
int fsave(char *name, MGPI_BYTE *file_buffer, int len) {
    FILE *fp;

    if (!(fp = fopen(name, "wt"))) {
        MGPI_PostMessagef("%s: couldn't open \"%s\"", __FUN__, name);
        return -1;
    }

    fwrite(file_buffer, sizeof (char), len, fp);
    fclose(fp);
    return len;
}

/**
 * Creates a charactes array of a given length, initialized with zeros.
 */
char *string(long length) {
    return (char *) calloc(length, sizeof (char));
}

/**
 * Gets time form the given system time in seconds.
 */
void debug_GetTime(double *t) {
    *t = fabs((double) (SDL_GetTicks() / 1000.0) - *t);
    return;
}
